useContextuseContext 是 React 提供的其中一個 Hook,用來讀取 Context 的資料。
在 React 中,資料通常需要透過 props 一層層傳遞(例如:App → Navbar → Button),但如果元件巢狀層級很深,就會變得麻煩。
這時候就可以用Context,建立「全域狀態」,讓不同元件間共享;而 useContext 則是能讓元件能快速讀取 Context 中的工具。
當「某個狀態需要在很多元件共享」時,就適合用 Context + useContext
常見的例子:
MyContext.js
import { createContext } from "react";
const MyContext = createContext();
export default MyContext;
createContext():建立 Context 容器MyContext:共享資料的入口MyProvider.js
import MyContext from "./MyContext";
import { useState } from "react";
function MyProvider({ children }) {
  const [value, setValue] = useState("(…)");
  return (
    <MyContext.Provider value={{ value, setValue }}>
      {children}
    </MyContext.Provider>
  );
}
export default MyProvider;
MyProvider:包住其他元件,負責提供資料<MyContext.Provider value={{value, setValue}}>:共享 value 和 setValue 給子元件使用註:children 是一個prop屬性,代表「被元件標籤包住的內容」
useContext 取得資料Child.js
import { useContext } from "react";
import MyContext from "./MyContext";
function Child() {
  const { value, setValue } = useContext(MyContext);
  return (
    <div>
      <p>{value}</p>
      <button onClick={() => setValue("New Value")}>
        更新資料
      </button>
    </div>
  );
}
useContext(MyContext):取出 Provider 提供的 value 和 setValue
<button onClick={() => setValue("New Value")}>:點擊按鈕後會更新 value → 畫面自動重新渲染App.js
import MyProvider from "./MyProvider";
import Child from "./Child";
function App() {
  return (
    <MyProvider>
      <Child />
    </MyProvider>
  );
}
<MyProvider> 包住整個應用程式,這樣 Child(或其他子元件)都能存取 value
import { createContext, useState } from "react";
const ThemeContext = createContext();
function ThemeProvider({ children }) {
  const [theme, setTheme] = useState("light");
  const toggleTheme = () => {
    setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
  };
  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      { children }
    </ThemeContext.Provider>
  );
}
export { ThemeProvider, ThemeContext };
ThemeContext:建立 Context,負責共享主題資料ThemeProvider:管理 theme 狀態,並提供 toggleTheme 切換主題value={{ theme, toggleTheme }}:讓 theme 和 toggleTheme 可以提供給子元件取用import Navbar from "./Navbar";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { ThemeProvider, ThemeContext } from "./ThemeContext";
import { useContext } from "react";
function App(){
  return (
    <ThemeProvider>
      <Router>
        <MainApp/>
      </Router>
    </ThemeProvider>
  );
}
function MainApp(){
  const { theme } = useContext(ThemeContext);
  return (
      <div className={`App ${theme}`}>
        <Navbar />
        <div className="content">
          <Routes>
            (...)
          </Routes>
        </div>
      </div>
  );
}
export default App;
<ThemeProvider>:包住整個 App,讓所有子元件能共享主題狀態useContext(ThemeContext):在 MainApp 取得目前 theme,並根據主題切換 className
import { useContext } from "react";
import { Link } from "react-router-dom";
import { ThemeContext } from "./ThemeContext";
const Navbar = () => {
  const { theme, toggleTheme } = useContext(ThemeContext);
  return (
    <nav className={`navbar ${theme}`}>
      <h1>The Blog</h1>
      <div className="links">
        (…)
        <button onClick={toggleTheme} className="theme-btn">
          {theme === "light" ? "Dark" : "Light"}
        </button>
      </div>
    </nav>
  );
};
export default Navbar;\
useContext(ThemeContext) :取得 theme 和 toggleTheme
<button onClick={toggleTheme} className="theme-btn">:點擊按鈕後可以切換主題.App.light (…)
.App.dark (…)
theme 加上的 className (light 或 dark),應用不同樣式,達到切換樣式的效果ThemeContext 和 ThemeProvider → 管理狀態<ThemeProvider> 包住應用程式 → 所有子元件都能存取主題useContext → 讀取 theme,並用按鈕切換主題.light 和 .dark → 顯示不同樣式瀏覽器執行畫面